package cn.edu.njust.websocket;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

@Slf4j
public class WebSocketServerHandler extends ChannelInboundHandlerAdapter {

    private static final ScheduledExecutorService executor = Executors.newScheduledThreadPool(8);
    private static final ConcurrentHashMap<String, ScheduledFuture> futureMap = new ConcurrentHashMap<>();

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        log.info("连接{}成功", ctx.channel().remoteAddress());
        ScheduledFuture<?> scheduleFuture = executor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                ctx.writeAndFlush(new TextWebSocketFrame("服务端周期性消息"));
            }
        }, 2, 2, TimeUnit.SECONDS);
        futureMap.put(ctx.channel().id().asLongText(), scheduleFuture);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        log.info("与{}断开连接", ctx.channel().remoteAddress());
        futureMap.get(ctx.channel().id().asLongText()).cancel(true);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        TextWebSocketFrame frame = (TextWebSocketFrame) msg;
        log.info("收到{}发来的消息：{}", ctx.channel().remoteAddress(), frame.text());
        ctx.writeAndFlush(new TextWebSocketFrame("收到了你发送的消息：" + frame.text()));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        if (futureMap.contains(ctx.channel().id().asLongText()))
            futureMap.get(ctx.channel().id().asLongText()).cancel(true);

        ctx.close();
    }
}
